package pub.tbc.api;

import com.google.common.collect.Lists;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import lombok.extern.slf4j.Slf4j;
import pub.tbc.api.config.ProjectConfig;
import pub.tbc.api.handler.HttpFilterHandler;
import pub.tbc.api.handler.InvokerHandler5;
import pub.tbc.api.util.Banner;

import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * @author tbc on 2017/3/1 18:03:14.
 */
@Slf4j
public class ApiGatewayApplication {

    private void banner(ProjectConfig projectConfig) {
        if (projectConfig.printBanner())
            new Banner().print();
    }

    /**
     * 处理链：
     * 1. 先从配置读，若有相关配置，则使用配置生成处理器列表；
     * 2. 若无配置，读取全部处理器，排除使用注解标不使用的；
     */
    private Map<String, ChannelHandler> handlerMap() {
        return null;
    }

    private List<ChannelHandler> handlers() {
        return Lists.newArrayList(
                new HttpRequestDecoder(),
                new HttpObjectAggregator(65535),
                new HttpResponseEncoder(),
//                new ChunkedWriteHandler(),
                new HttpFilterHandler(),
                new InvokerHandler5()
        );
    }

    private void start(ProjectConfig projectConfig) {
        // banner print
        banner(projectConfig);

        // 根据配置，生成处理链列表（有序）
        Map<String, ChannelHandler> mapHandlers = handlerMap();

        // 创建netty server
        HttpNettyServer httpNettyServer = () -> {
            return new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    handlers().forEach(handler -> {
                        System.out.println("add handler ===> " + handler.getClass().getName());
                        ch.pipeline().addLast(handler);
                    });
                }
            };
        };

        // 开始监听端口，启动完毕
        int port = projectConfig.httpPort();
        httpNettyServer.bind(port);
        log.info("ApiGateway started, listener port: {}", port);
    }

    public static void main(String[] args) {
        new ApiGatewayApplication().start(ProjectConfig.instance());
    }


}
